package top.milkbox.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 0与时间相关的方法
 * <p>
 * G 年代标志符
 * <p>
 * y 年
 * <p>
 * M 月
 * <p>
 * d 日
 * <p>
 * h 时 在上午或下午 （1~12）
 * <p>
 * H 时 在一天中 （0~23）
 * <p>
 * m 分
 * <p>
 * s 秒
 * <p>
 * S 毫秒
 * <p>
 * E 星期
 * <p>
 * D 一年中的第几天
 * <p>
 * F 一月中第几个星期几
 * <p>
 * w 一年中第几个星期
 * <p>
 * W 一月中第几个星期
 * <p>
 * a 上午 / 下午 标记符
 * <p>
 * z 时区
 *
 * @author xiaoguo
 */
public class GuoUtilsDate {

    // 一天是86400000毫秒，OneDayTime
    public final static int ONEDAYTIME = 86400000;

    // 一小时是3600000毫秒，OneHourTime
    public final static int ONEHOURTIME = 3600000;

    // 一分钟是60000毫秒，OneMinuteTime
    public final static int ONEMINUTETIME = 60000;

    // 一秒是1000毫秒，OneSecondTime
    public final static int ONESECONDTIME = 1000;

    /**
     * 获取指定日期是星期几 参数为null时表示获取当前日期是星期几
     *
     * @param strDate 时间字符串（如2019-10-29）
     * @return 返回星期
     * @author guo
     */

    public static String getWeekOfDate(String strDate) {
        String[] weekOfDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        int w = 0;
        try {
            if (strDate == null) {
                date = null;
            } else {
                date = dateFormat.parse(strDate);
            }
            if (date != null) {
                calendar.setTime(date);
            }
            w = calendar.get(Calendar.DAY_OF_WEEK) - 1;
            if (w < 0) {
                w = 0;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return weekOfDays[w];
    }

    /**
     * 将给定的时间加day天（可以为负数）
     *
     * @param date 指定的时间
     * @param day  增加天数（可以为负数）
     * @return 返回计算后的时间
     */
    public static Date dateAdd(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 获取当前的时间，默认格式：yyyy-MM-dd HH:mm:ss
     *
     * @return 返回时间字符串
     */
    public static String getDateNow() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    /**
     * 通过指定的格式获取当前的时间
     *
     * @return 返回时间字符串
     */
    public static String getDateNow(String simpleDate) {
        return new SimpleDateFormat(simpleDate).format(new Date());
    }

    /**
     * 将date类型转换为字符类型，格式自定义
     *
     * @param date       date类型数据
     * @param simpleDate 转换的模板
     * @return 返回字符串
     */
    public static String dateToString(Date date, String simpleDate) {
        return new SimpleDateFormat(simpleDate).format(date);
    }

    /**
     * 通过指定的字符串转化为date类型（默认传入格式：yyyy/MM/dd HH:mm:ss），如果传入格式错误则会报错并返回null
     *
     * @param dateString 传入的字符串
     * @return 返回date类型
     */
    public static Date getDateFromString(String dateString) {
        try {
            return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
                    .parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据指定的时间格式dateFormat，将字符串dateString转换为date类型，如果传入格式错误则会报错并返回null
     *
     * @param dateFormat 时间格式
     * @param dateString 要转换的字符串
     * @return 返回date类型
     */
    public static Date getDateFromString(String dateFormat, String dateString) {
        try {
            return new SimpleDateFormat(dateFormat).parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取两个时间之间的时间，即两个时间相减
     *
     * @param date1 起始时间
     * @param date2 结束时间
     * @return 返回xx天xx时xx分xx秒xx毫秒，字符串
     */
    public static String getBetweenTwoDate(Date date1, Date date2) {
        long time = date2.getTime() - date1.getTime();
        int day = (int) (time / ONEDAYTIME); // 天数
        int residueDay = (int) (time % ONEDAYTIME); // 不足一天的剩余的毫秒值
        int hour = residueDay / ONEHOURTIME; // 小时
        int residueHour = residueDay % ONEHOURTIME; // 不足一小时的剩余的毫秒值
        int minute = residueHour / ONEMINUTETIME; // 分钟
        int residueMinute = residueHour % ONEMINUTETIME; // 不足一分钟的剩余毫秒值
        int second = residueMinute / ONESECONDTIME; // 秒
        int residueTime = residueMinute % ONESECONDTIME; // 不足一秒的剩余毫秒值
        return "" + day + "天" + hour + "时" + minute + "分钟" + second + "秒" + residueTime + "毫秒";
    }

    /**
     * 获取当前时间不足一天的剩余的毫秒值
     * @param date 时间
     * @return 不足一天的剩余的毫秒值
     */
    public static long getResidueDay(Date date) {
        long time = date.getTime();
        int residueDay = (int) (time % ONEDAYTIME); // 不足一天的剩余的毫秒值
        return residueDay;
    }

}

